package com.platform.wechat.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.platform.wechat.entity.WxUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author CX
 * @create 2021-07-12 15:16
 */
@Component
public class Constant {

    /** Logger实例 */
    static final Logger logger = LoggerFactory.getLogger(Constant.class);

    //上次获取access_token的时间
    public static Long ACCESSTOKENTIME = 1L;
    //获取到的access_token
    public static String ACCESSTOKEN = "";
    //上次获取jsapiTicket的时间
    public static Long JSAPITICKETTIME = 1L;
    //上次获取ticket的时间
    public static Long EXPIRESECONDS = 1L;
    //获取到的jsapiTicket
    public static String JSAPITICKET = "";

    //静默授权
    public static final String SNSAPI_BASE = "snsapi_base";
    //用户手动同意授权
    public static final String SNSAPI_USERINFO = "snsapi_userinfo";

    private static RedisTemplate redisTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        Constant.redisTemplate = redisTemplate;
    }


    /**
     * 通过redisGEO计算两地经纬度距离
     * @param blongitude B1经度
     * @param blatitude  B1维度
     * @param ulongitude B2经度
     * @param ulatitude  B2维度
     * @return
     */
    public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2){
        double latDistance = Math.toRadians(longitude1 - longitude2);
        double lngDistance = Math.toRadians(latitude1 - latitude2);

        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(longitude1)) * Math.cos(Math.toRadians(longitude2))
                * Math.sin(lngDistance / 2) * Math.sin(lngDistance / 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return c * 6378.137;
    }

    /**
     * 获取微信公众号js接口调用凭据
     * @return
     */
    public static String getJsapiTicket(){
        long nowTime = System.currentTimeMillis()/1000;
        if((nowTime - JSAPITICKETTIME) > 7000){
            String url = WechatAPI.JSAPITICKETURL.replace("ACCESS_TOKEN", getAccessToken());
            String s = HttpClientUtil.doGet(url);
            System.out.println("获取到的jsapiTicket:"+s);
            JSONObject jsonObject = JSON.parseObject(s);
            if(jsonObject.getString("errcode").equals("0")){
                JSAPITICKETTIME = System.currentTimeMillis()/1000;
                JSAPITICKET = jsonObject.getString("ticket");
            }
        }
        return JSAPITICKET;
    }

    /**
     * 获取js接口权限签名
     * @param url
     * @return
     */
    public static Map<String, String> getSignature(String url){
        String jsapi_ticket = getJsApiTicket();
        String noncestr = Tools.getNoncestr();
        String timestamp = System.currentTimeMillis()/1000 + "";
        String str = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" +noncestr +
                "&timestamp=" +timestamp +
                "&url=" + url;
        String signature = Tools.getSha1Str(str);
        Map<String, String> map = new HashMap<>();
        map.put("appId", WechatAPI.APPID);
        map.put("timestamp", timestamp);
        map.put("nonceStr", noncestr);
        map.put("signature", signature);
        logger.debug("getSignature ： " + map.toString());
        return map;
    }

    /**
     * 获取access_token方法
     *
     * @return
     */
    public static String getAccessToken() {
        long nowTime = System.currentTimeMillis()/1000;
        if (nowTime - ACCESSTOKENTIME > 7000) {
            String url = WechatAPI.ACCESSTOKENURL.replace("APPID", WechatAPI.APPID).replace("APPSECRET", WechatAPI.APPSECRET);
            String s = HttpClientUtil.doGet(url);
            JSONObject jsonObject = JSON.parseObject(s);
            if (jsonObject.containsKey("access_token")) {
                ACCESSTOKEN = jsonObject.getString("access_token");
                ACCESSTOKENTIME = System.currentTimeMillis()/1000;
            }
        }
        return ACCESSTOKEN;
    }

    /**
     * 临时使用获取AccessToken
     * @return
     */
    public static String getTemporaryAccessToken() {
        String url = WechatAPI.ACCESSTOKENURL.replace("APPID", WechatAPI.APPID).replace("APPSECRET", WechatAPI.APPSECRET);
        String s = HttpClientUtil.doGet(url);
        JSONObject jsonObject = JSON.parseObject(s);
        if(jsonObject.containsKey("access_token")){
            return jsonObject.get("access_token").toString();
        }
        return "";
    }

    public static WxUser getWxUserInfo(String openid) {
        WxUser wxUser = null;
        String url = WechatAPI.GETWXUSERINFO.replace("ACCESS_TOKEN", getAccessToken()).replace("OPENID", openid);
        String result = HttpClientUtil.doGet(url);
        JSONObject jsonObject = JSON.parseObject(result);
        if (!jsonObject.containsKey("errcode")) {
            wxUser = JSON.parseObject(result, WxUser.class);
        }
        return wxUser;
    }

    /**
     * 获取网页授权连接（用户手动同意授权）
     * @param url
     * @return
     */
    public static String getUrl(String url,String scope){
        try {
            String encode = URLEncoder.encode(url,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return WechatAPI.OAUTH_URL.replace("APPID", WechatAPI.APPID).replace("REDIRECT_URI", url).replace("SCOPE", scope);
    }

    /**
     * 微信网页授权
     * @param uri
     * @return
     */
    public static String oAuth(String uri, String scope){
        try {
            uri = URLEncoder.encode(uri, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return WechatAPI.OAUTH_URL.replace("APPID", WechatAPI.APPID).replace("REDIRECT_URI", uri).replace("SCOPE", scope);
    }

    /**
     * 通过code换取access_token和openid
     * @param code
     * @return
     */
    public static JSONObject getAccessTokenAndOpenid(String code){
        JSONObject jsonObject = null;
        String url = WechatAPI.OAUTH2ACCESSTOKEN.replace("APPID", WechatAPI.APPID).replace("SECRET", WechatAPI.APPSECRET).replace("CODE", code);
        String s = HttpClientUtil.doGet(url);
        jsonObject = JSON.parseObject(s);
        System.err.println(jsonObject);
        return jsonObject;
    }

    /**
     * 获取jsapi_ticket
     * @return
     */
    private static String getJsApiTicket() {
        Object jsapi_ticket = redisTemplate.opsForValue().get("jsapi_ticket");
        if(jsapi_ticket == null){
            String url = WechatAPI.JSAPITICKETURL.replace("ACCESS_TOKEN", getAccessToken());
            String s = HttpClientUtil.doGet(url);
            logger.debug("jsapi_ticket ： " + s);
            JSONObject jsonObject = JSON.parseObject(s);
            if(jsonObject.containsKey("ticket")){
                jsapi_ticket = jsonObject.get("ticket");
                redisTemplate.opsForValue().set("jsapi_ticket", jsapi_ticket.toString(), 2, TimeUnit.HOURS);
            }
        }
        return jsapi_ticket.toString();
    }

    /**
     * 网页授权获取用户信息
     * @param accessToken
     * @param openid
     * @return
     */
    public static WxUser getWxUserSnsUserInfo(String accessToken,String openid){
        WxUser wxUser = null;
        String url = WechatAPI.SNSUSERINFO.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);
        String s = HttpClientUtil.doGet(url);
        wxUser = JSON.parseObject(s, WxUser.class);
        return wxUser;
    }

    /**
     * 调用获取微信用户信息接口UnionID机制
     * @param openid
     * @return
     */
    public static WxUser getWxUserInfoByUnionID(String openid){
        String url = WechatAPI.GETWXUSERINFO.replace("ACCESS_TOKEN", getAccessToken()).replace("OPENID", openid);
        String s = HttpClientUtil.doGet(url);
        logger.debug("getWxUserInfoByUnionID ： " + s);
        return GsonUtil.josnToModule(s, WxUser.class);
    }

    /**
     * 发送模板消息
     * @param data
     * @return
     */
    public static boolean sendTemplate(String data){
        String url = WechatAPI.SENDTEMPLATE_URL.replace("ACCESS_TOKEN", getAccessToken());
        String s = HttpClientUtil.doPost(url, data);
        logger.debug("sendTemplate ： " + s);
        JSONObject jsonObject = JSON.parseObject(s);
        if(jsonObject.get("errcode").toString().equals("0")){
            return true;
        }
        return false;
    }

    /**
     * 挂号成功模板; 候诊时间： {{keyword1.DATA}} 就诊医院： {{keyword2.DATA}} 就诊科室： {{keyword3.DATA}} 就诊人： {{keyword4.DATA}} 备注： {{remark.DATA}}
     * 退号成功模板; 就诊人： {{keyword4.DATA}} 就诊医院： {{keyword2.DATA}} 就诊科室： {{keyword3.DATA}} 候诊时间： {{keyword1.DATA}}
     * @param map   openid, template_id, url, waitingTime, hospital, department, patient
     * @return
     */
    public static String registrationOrWithdrawal(Map<String, Object> map){
        JSONObject json = new JSONObject();
        json.put("touser", map.get("openid").toString());
        json.put("template_id", map.get("template_id").toString());
        json.put("url", map.get("url").toString());
        JSONObject data = new JSONObject();
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", map.get("waitingTime").toString());
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", map.get("hospital").toString());
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", map.get("department").toString());
        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", map.get("patient").toString());
        JSONObject remark = new JSONObject();
        remark.put("value", map.get("remark"));
        data.put("keyword1", keyword1);
        data.put("keyword2", keyword2);
        data.put("keyword3", keyword3);
        data.put("keyword4", keyword4);
        data.put("remark", remark);
        json.put("data", data);
        return json.toString();
    }

    public static void main(String[] args) {
        //System.err.println(getAccessTokenAndOpenid(""));
    }

}
